home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / unixSyscall / brk.c < prev    next >
C/C++ Source or Header  |  1989-04-12  |  4KB  |  147 lines

  1. /* 
  2.  * brk.c --
  3.  *
  4.  *    Source code for the "brk" and "sbrk" library procedures, which
  5.  *    emulate the UNIX kernel calls by the same names.
  6.  *
  7.  * Copyright 1985, 1988 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/lib/c/unixSyscall/RCS/brk.c,v 1.7 89/04/12 17:11:23 rab Exp $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include <sprite.h>
  22. #include <stdio.h>
  23. #include <vm.h>
  24. #include <sys/types.h>
  25.  
  26. /*
  27.  * NextAddr is the user's idea of the location of the first
  28.  * as-yet-unallocated byte in the heap.  RealNextAddr is the
  29.  * real location.  We keep two pointers so we if a program
  30.  * asks brk() to reduce the size of the heap, we can shrink
  31.  * is without making any actual system calls.  The space is
  32.  * still allocated, so subsequent requests to extend the heap
  33.  * can also be met without system calls.
  34.  */
  35.  
  36. extern int end;                /* Linker gives this variable an
  37.                      * address equal to the location just
  38.                      * above the top of the heap. */
  39. #ifndef LINTLIB
  40. static caddr_t nextAddr = (caddr_t) &end;
  41. static caddr_t realNextAddr = (caddr_t) &end;
  42. #else
  43. static caddr_t nextAddr = 0;
  44. static caddr_t realNextAddr = 0;
  45. #endif /* LINTLIB */
  46. static int pageSize;
  47.  
  48. /*
  49.  * Macro to compute for any address, the first addresss of the page
  50.  * it is on.
  51.  */
  52.  
  53. #define FirstAddrOnPage(address)  (((int) (address)) & (~pageSize))
  54.  
  55.  
  56. /*
  57.  *----------------------------------------------------------------------
  58.  *
  59.  * brk --
  60.  *
  61.  *    Enlarge the heap, if necessary, so that it extends to at
  62.  *    least addr-1.
  63.  *
  64.  * Results:
  65.  *    0 is normally returned.  If the heap couldn't be extended
  66.  *    to the given place, then -1 is returned.
  67.  *
  68.  * Side effects:
  69.  *    The virtual address space of the process is extended.
  70.  *
  71.  *----------------------------------------------------------------------
  72.  */
  73.  
  74. caddr_t
  75. brk(addr)
  76.     caddr_t addr;        /* Make this the new "first location just
  77.                  * above top of heap".  */
  78. {
  79.     static int initialized = 0;
  80.     ReturnStatus status;
  81.  
  82.     if (!initialized) {
  83.         initialized = 1;
  84.  
  85.     /*
  86.      *  Get the system page size and calculate the address in the heap 
  87.      *  after the end of data to start allocating chunks from.
  88.      */
  89.  
  90.     if (Vm_PageSize(&pageSize) != SUCCESS) {
  91.         panic("brk couldn't get page size");
  92.         return 0;        /* should never get here */
  93.     }
  94.     pageSize -= 1;
  95.     }
  96.  
  97.     /*
  98.      * See if the new top-of-heap is already mapped;  if so, there's
  99.      * nothing for us to do.
  100.      */
  101.  
  102.     if (addr <= realNextAddr) {
  103.     nextAddr = addr;
  104.     return 0;
  105.     }
  106.     if(FirstAddrOnPage(realNextAddr - 1) != FirstAddrOnPage(addr)) {
  107.     status = Vm_CreateVA(realNextAddr, addr-realNextAddr);
  108.     if (status != SUCCESS) {
  109.         return (caddr_t) -1;
  110.     }
  111.     }
  112.     realNextAddr = nextAddr = addr;
  113.     return 0;
  114. }
  115.  
  116. /*
  117.  *----------------------------------------------------------------------
  118.  *
  119.  * sbrk --
  120.  *
  121.  *    Make "numBytes" more space available in the heap, and return
  122.  *    a pointer to it.
  123.  *
  124.  * Results:
  125.  *    The return value is a pointer to a new block of memory, which
  126.  *    is numBytes bytes long.  If no space could be allocated, then
  127.  *    -1 is returned.
  128.  *
  129.  * Side effects:
  130.  *    The virtual address space of the process is extended.
  131.  *
  132.  *----------------------------------------------------------------------
  133.  */
  134.  
  135. caddr_t
  136. sbrk(numBytes)
  137.     int numBytes;            /* Number of bytes desired.  */
  138. {
  139.     caddr_t result;
  140.  
  141.     result = nextAddr;
  142.     if (brk(nextAddr+numBytes) == (caddr_t) -1) {
  143.     return (caddr_t) -1;
  144.     }
  145.     return result;
  146. }
  147.